#include <IntroState.h>
#include <PlayState.h>

template<> IntroState* Ogre::Singleton<IntroState>::ms_Singleton = 0;

IntroState::IntroState()
{
  _pTrackManager = NULL;
}

void IntroState::enter()
{
  _root = Ogre::Root::getSingletonPtr();

  try {
    _sceneMgr = _root->createSceneManager(Ogre::ST_GENERIC, "SceneManager"); }

  catch (Ogre::ItemIdentityException e) {
    _sceneMgr = _root->getSceneManager("SceneManager"); }

  // Cursor
  _overlayMgr = Ogre::OverlayManager::getSingletonPtr();
  _overlayMgr->getByName("HUD")->show();
  _mouseOverlay = _overlayMgr->getOverlayElement("cursor");
  _overlayMgr->getOverlayElement("life")->hide();
  _overlayMgr->getOverlayElement("zlife")->hide();
  _overlayMgr->getOverlayElement("screen")->hide();
  _overlayMgr->getOverlayElement("score")->hide();
  _overlayMgr->getOverlayElement("win")->hide();
  _overlayMgr->getOverlayElement("lose")->hide();

  // Audio
  if (_pTrackManager == NULL)
    _pTrackManager = new TrackManager;

  _ost = _pTrackManager->load("intro.ogg");
  _ost->play();

//  _pTrackManager->load("soviet_anthem.ogg")->play();

  // Ray
  _raySceneQuery = _sceneMgr->createRayQuery(Ogre::Ray());

  // Variables
  _exitGame = false;

  // Camara
  Ogre::Camera* cam = _sceneMgr->getCamera("MainCamera");
  cam->setPosition(Ogre::Vector3(2.09216,4.11393,13.2123));
  cam->lookAt(Ogre::Vector3(0.5,2,0));
  cam->setNearClipDistance(5);
  cam->setFarClipDistance(10000);

  // Crear escena menu
  createScene();
}

void IntroState::exit()
{
  // Audio
//  _pTrackManager->load("soviet_anthem.ogg")->stop();
//  delete _pSoundFXManager;
//  delete _pTrackManager;

  _sceneMgr->destroyQuery(_raySceneQuery);
  _sceneMgr->clearScene();
  _root->getAutoCreatedWindow()->removeAllViewports();
}

void IntroState::pause() {
  _ost->stop(); }

void IntroState::resume() {}

bool IntroState::frameStarted(const Ogre::FrameEvent& evt)
{
  Ogre::Real deltaT = evt.timeSinceLastFrame;

  return not _exitGame;
}

bool IntroState::frameEnded(const Ogre::FrameEvent& evt) {
  return not _exitGame; }

void IntroState::keyPressed(const OIS::KeyEvent& e)
{
  if (e.key == OIS::KC_ESCAPE)
    _exitGame = true;
}

void IntroState::keyReleased(const OIS::KeyEvent& e ) {}

void IntroState::mouseMoved(const OIS::MouseEvent& e) {

  int posx = e.state.X.abs;
  int posy = e.state.Y.abs;

  _mouseOverlay->setLeft(posx);
  _mouseOverlay->setTop(posy);
}

void IntroState::mousePressed(const OIS::MouseEvent& e, OIS::MouseButtonID id) {

  _sceneMgr->clearScene();
  pushState(PlayState::getSingletonPtr());
}

void IntroState::mouseReleased(const OIS::MouseEvent& e, OIS::MouseButtonID id) {}

Ogre::Ray IntroState::setRayQuery(int posx, int posy, Ogre::uint32 mask)
{
  Ogre::Ray rayMouse = _camera->getCameraToViewportRay
    (posx/float(_root->getAutoCreatedWindow()->getWidth()),
     posy/float(_root->getAutoCreatedWindow()->getHeight()));
  _raySceneQuery->setRay(rayMouse);
  _raySceneQuery->setSortByDistance(true);
  _raySceneQuery->setQueryMask(mask);
  return (rayMouse);
}

IntroState* IntroState::getSingletonPtr() {
  return ms_Singleton; }

IntroState& IntroState::getSingleton()
{
  assert(ms_Singleton);
  return *ms_Singleton;
}

void
IntroState::createScene() {

  Ogre::Entity* suelo = _sceneMgr->createEntity("Suelo.mesh");
  Ogre::Entity* arboles = _sceneMgr->createEntity("Arboles.mesh");
  Ogre::Entity* cruces = _sceneMgr->createEntity("Cruces.mesh");
  Ogre::Entity* titulo = _sceneMgr->createEntity("Titulo.mesh");
  Ogre::Entity* tumba = _sceneMgr->createEntity("Tumba.mesh");
  Ogre::Entity* mano = _sceneMgr->createEntity("Mano.mesh");
  Ogre::Entity* cuervo = _sceneMgr->createEntity("Cuervo.mesh");
  Ogre::Entity* cono = _sceneMgr->createEntity("Cone.mesh");
  Ogre::Entity* cartel = _sceneMgr->createEntity("Cartel.mesh");
  Ogre::Entity* nombres = _sceneMgr->createEntity("Nombres.mesh");
  Ogre::Entity* cielo = _sceneMgr->createEntity("sky.mesh");
  Ogre::Entity* linterna = _sceneMgr->createEntity("Linterna.mesh");

  Ogre::SceneNode* node1 = _sceneMgr->createSceneNode("Menu");

  node1->setScale (1,1,1);
  node1->attachObject(suelo);
  node1->attachObject(arboles);
  node1->attachObject(cruces);
  node1->attachObject(titulo);
  node1->attachObject(tumba);
  node1->attachObject(mano);
  node1->attachObject(cuervo);
  node1->attachObject(cono);
  node1->attachObject(linterna);
  node1->attachObject(cartel);
  node1->attachObject(nombres);
  node1->attachObject(cielo);

  _sceneMgr->getRootSceneNode()->addChild(node1);

  _sceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

  Ogre::Light* moon = _sceneMgr->createLight("Moon");
  moon->setType(Ogre::Light::LT_POINT);
  moon->setPosition(Ogre::Vector3(8,12,-14));
  moon->setDirection(Ogre::Vector3(0,0,0));
  moon->setDiffuseColour(0.578,0.522,1.0);

  Ogre::Light* torch = _sceneMgr->createLight("Torch");
  torch->setType(Ogre::Light::LT_SPOTLIGHT );
  torch->setPosition(Ogre::Vector3(-2.122,0.133,0.278));
  torch->setDirection(Ogre::Vector3(11.5505,3.9633,-5.7271));

  node1->attachObject(moon);
  node1->attachObject(torch);
}
